package com.gengzp.system.service.impl;

import com.gengzp.common.exception.BusinessException;
import com.gengzp.common.model.user.entity.SysUser;
import com.gengzp.common.model.user.req.AddSysUserReq;
import com.gengzp.common.model.user.req.EditUserPasswordReq;
import com.gengzp.common.model.user.req.LoginUserReq;
import com.gengzp.common.model.user.resp.LoginUserResp;
import com.gengzp.common.utils.EncryptionUtils;
import com.gengzp.common.utils.RandomUtils;
import com.gengzp.permission.utils.PermissionUtils;
import com.gengzp.system.facade.IPermissionFacade;
import com.gengzp.system.facade.ISysUserFacade;
import com.gengzp.system.service.ISysUserAuthenticationService;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collections;
import java.util.List;
import java.util.Objects;

/**
 * @ClassName UserAuthenticationServiceImpl
 * @Description 用户认证服务层
 * @Author gengzp
 * @Date 2025/5/11 3:22
 */
@Service
public class SysUserAuthenticationServiceImpl implements ISysUserAuthenticationService {

    private static final Logger logger = LoggerFactory.getLogger(SysUserAuthenticationServiceImpl.class);

    @Autowired
    private ISysUserFacade sysUserFacade;

    @Autowired
    private IPermissionFacade permissionFacade;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public LoginUserResp doRegister(AddSysUserReq req) {
        // 校验用户账号和昵称是否重复
        if (CollectionUtils.isNotEmpty(sysUserFacade.searchSysUserByUserAccountAndUserNickname(req.getUserAccount(), req.getUserNickname()))) {
            throw BusinessException.get("用户账号或昵称已存在");
        }

        // 组装用户信息
        SysUser sysUser = new SysUser();
        sysUser.setUserAccount(req.getUserAccount());
        sysUser.setUserNickname(req.getUserNickname());

        // 生成用户随机盐值, 并对密码进行加密
        String salt = RandomUtils.createRandomString(10);
        sysUser.setSalt(salt);
        sysUser.setUserPassword(EncryptionUtils.md5hex(req.getUserPassword() + salt));
        sysUser.setUserIntroduction("这个人很懒， 什么都没有留下...");

        // 添加用户时, 登录状态一定为空, 因此需要手动填充 创建人, 最后一次修改人 字段
        sysUser.setCreatedBy(sysUser.getId());
        sysUser.setLastModifiedBy(sysUser.getId());

        // 创建系统用户
        sysUserFacade.addSysUser(sysUser);
        // 注册完成时, 自动登录, 使用权限框架返回token
        return new LoginUserResp(sysUser.getId(), sysUser.getUserNickname(),
                PermissionUtils.doLogin(sysUser.getId(), req.getClientType(), Collections.emptyList())
                        .getToken());
    }

    @Override
    public LoginUserResp doLogin(LoginUserReq req) {
        // 当前登录用户的id
        Long loginSysUserId;
        // 当前登录的用户昵称
        String loginSysUserNickname;
        // 当前登录用户的密码
        String loginSysUserPassword;
        // 当前登录用户的盐值
        String loginSysUserSalt;
        // 当前登录用户的角色集合
        List<Long> loginSysUserRoleIds = Lists.newArrayList();

        // 先校验当前登录账号是否为超级管理员
        if (StringUtils.equals(req.getUserAccount(), PermissionUtils.getSuperAdminUserAccount())) {
            loginSysUserId = Long.valueOf(PermissionUtils.getSuperAdminUserId());
            loginSysUserNickname = "超级管理员";
            loginSysUserPassword = PermissionUtils.getSuperAdminUserPassword();
            loginSysUserSalt = PermissionUtils.getSuperAdminUserSalt();
        } else {
            // 不是超级管理员, 则从数据库中查询用户信息
            List<SysUser> sysUsers = sysUserFacade.searchSysUserByUserAccountAndUserNickname(req.getUserAccount(), null);
            if (CollectionUtils.isEmpty(sysUsers)) {
                throw BusinessException.get("该用户账号不存在");
            }
            SysUser loginSysUser = sysUsers.get(0);
            loginSysUserId = loginSysUser.getId();
            loginSysUserNickname = loginSysUser.getUserNickname();
            loginSysUserPassword = loginSysUser.getUserPassword();
            loginSysUserSalt = loginSysUser.getSalt();
            loginSysUserRoleIds = permissionFacade.searchRoleIdsByUserId(loginSysUserId);
        }

        // 校验加密后的密码是否一致
        if (!StringUtils.equals(EncryptionUtils.md5hex(req.getUserPassword() + loginSysUserSalt), loginSysUserPassword)) {
            throw BusinessException.get("密码输入错误");
        }

        // 使用权限框架登录并返回token, 组装返回对象
        return new LoginUserResp(loginSysUserId, loginSysUserNickname,
                PermissionUtils.doLogin(loginSysUserId, req.getClientType(), loginSysUserRoleIds).getToken());
    }

    @Override
    public void doQuit(String token) {
        // 使用权限框架退出登录
        PermissionUtils.doQuit(PermissionUtils.getCurrentUserId(), PermissionUtils.getCurrentUserToken());
    }

    @Override
    public void doEditPassword(EditUserPasswordReq req) {
        // 查出要修改密码的用户信息
        SysUser sysUser = sysUserFacade.searchSysUserById(Long.valueOf(req.getId()));
        if (Objects.isNull(sysUser)) {
            throw BusinessException.get("当前用户已经不存在");
        }

        // 比对旧密码输入是否正确
        if (!StringUtils.equals(sysUser.getUserPassword(),
                EncryptionUtils.md5hex(req.getOldPassword() + sysUser.getSalt()))) {
            throw BusinessException.get("旧密码输入错误");
        }

        // 比对新密码和旧密码是否一致
        if (!StringUtils.equals(req.getOldPassword(), req.getNewPassword())) {
            throw BusinessException.get("新密码不能和旧密码一致");
        }

        // 将新密码落库
        sysUser.setUserPassword(EncryptionUtils.md5hex(req.getNewPassword() + sysUser.getSalt()));
        sysUserFacade.editSysUser(sysUser);
    }

}
